*
* Simple File Search Utility
* Revision 1.00
* Written by Alan D. Bryant
* for eSoft, Inc.
*
****************************************************************************
* This program source is included with your TDBS to illustrate techniques. *
* You may use any or all of the source or techniques illustrated in this *
* program in any fashion you wish. There are no fees or restrictions *
* imposed on the use of this code by eSoft, Inc. *
****************************************************************************
*
* PURPOSE: This program implements a simple text search and
* download utility. The program is "pointed" to a particular file mask
* via Opt Data, then a user can perform a single key keyword search on
* all the files which are included in that mask.
*
* Files which match are stored in a database, and can then be downloaded
* after the search is completed. If too many files matched, they can
* be downloaded in groups.
*
* Batch protocols must be used the way the program is currently structured,
* and the download function is called in such a way as to prevent use of
* non-batch protocols.
*
* CONCEPTS ILLUSTRATED: Several concepts are outlined here, including
* the use of the file I/O system, building temporary databases, use of
* the file I/O system's text search capability, multi-file accesses, and
* much more. This program could serve as the engine for
*
* If you have the regular version of TDBS (with the compiler), there are
* many changes and enhancements which could be made to this program.
* These include the ability to use non-batch protocols or to read the files
* online; multiple key searches; a better user interface; etc. Think about
* the possibilities!
*
*
* initial stuff
set exclusive off
clear
* parse the opt data comments out
offset = at(chr(38)+chr(38), optdata())
* the opt data line isn't formatted properly
if offset = 0
? "SFILE: Opt data command line improperly configured."
key = inkey(2)
quit
endif
* if there's a space included, note that so it can be ignored
if substr(optdata(), offset + 2, 1) = " "
offset = offset + 1
endif
* get the file mask out of the Opt Data, and then get out just the
* root so it can be used later on
* the "mask" is used for the findfirst function
* the "root" is the mask with the filename reference removed
* e.g., C:\TDBS\APPS\SFILE /Q && D:\TEXT\SFILE\TECH*.TXT Opt Data
* D:\TEXT\SFILE\TEXT*.TXT Mask
* D:\TEXT\SFILE\ Root
mask = substr(optdata(), offset + 2)
backoff = rat("\", mask)
if backoff # 0
root = substr(mask, 1, backoff)
else
root = ""
endif
* find the first match occurrance of the mask
fname = findfirst(intern, mask)
* if findfirst() returns a null string, nothing was found which matches
if empty(fname)
? "SFILE: No files match the search mask in Opt Data."
key = inkey(2)
quit
else
* we're here if a match was found; build a temporary database
create newstruc
use newstruc
append blank
replace field_name with "MATCH", field_type with "C", field_len with 12
use
ourname = "SFILE"+uline()
create &ourname from newstruc
erase newstruc.dbf
use &ourname
* prompt for a search key and confirm
accept "Enter a search key? " to skey
? ""
? "Initiate a search for "+chr(34)+skey+chr(34)+"? (Y/N) "
key = inkey(0)
sel = upper(chr(key))
if sel = "N"
quit
endif
? ""
? "Initiating search. This could take a few moments..."
* open the file for the first found occurrance
do while .t.
fopen handle (root+fname) 10 2048
if handle = -1
? "SFILE: File open error"
? "SFILE: "+root+fname+" - "+message(ferror())
wait
quit
endif
* issue an flfind to search for the string in this file
? "Searching "+fname+"..."
flfind handle matchoff rtrim(skey) 1
fclose
if matchoff = -1
? "SFILE: File search error"
? "SFILE: "+root+fname+" - "+message(ferror())
wait
quit
endif
* if the search key was found in the file, append its name to
* the temp database for later
if matchoff # 0
append blank
replace MATCH with fname
endif
* find the next occurrance of the mask; if nothing is found,
* exit the loop
fname = findnext(intern)
if empty(fname)
exit
endif
enddo
* we're done with the searching; if the database has no records in it
* then no matches were found; report and quit; otherwise, start downloading
* of files
if reccount() = 0
? "No matches were found for your search key."
wait
quit
else
* toolong is used to keep track of whether or not there are too
* many matching files by getting the size of the opt data when
* built
toolong = 0
* prompt whether to download the files
? "A total of "+ltrim(str(reccount()))+" files matched your criteria."
? "Would you like to download the matched files? (Y/N)"
key = inkey(0)
sel = upper(chr(key))
if sel = "N"
quit
endif
* start the process of downloading by building the opt data first
* the build an opt data and allow download to begin
goto top
do while .t.
filelist = ""
do while .not. eof()
filelist = filelist+rtrim(match)+" "
skip
pointer = recno()
if len(filelist) > 80
if toolong = 0
? "The list of files is long. You'll have to download them in batches."
wait
toolong = 1
endif
exit
endif
enddo
command = root+" /P:6789AB/NL/I:"+chr(34)+"D "+filelist+chr(34)
if toolong = 0
wait
endif
dotbbs type 34 optdata command
use &ourname
if pointer < reccount()
goto pointer
else
exit
endif
enddo
endif
endif